<template>
  <div class="seat-selection-container">
    <h1>选择座位</h1>

    <div v-if="loading" class="loading">
      <el-skeleton :rows="10" animated />
    </div>

    <div v-else>
      <div class="showtime-info">
        <h2>{{ showtime?.movie?.title }}</h2>
        <p>放映时间: {{ formatDateTime(showtime?.showTime) }}</p>
        <p>影厅: {{ showtime?.hallName }}</p>
        <p>票价: ¥{{ showtime?.price }}</p>
      </div>

      <div class="seat-map-container">
        <div class="screen">银幕</div>

        <div class="seat-map">
          <div
            v-for="row in seatMap"
            :key="row.rowIndex"
            class="seat-row"
          >
            <div class="row-label">{{ row.rowIndex + 1 }}</div>
            <div
              v-for="seat in row.seats"
              :key="`${row.rowIndex}-${seat.columnIndex}`"
              class="seat"
              :class="{
                'occupied': seat.status === 'OCCUPIED',
                'selected': isSelected(row.rowIndex, seat.columnIndex),
                'available': seat.status === 'AVAILABLE'
              }"
              @click="toggleSeat(row.rowIndex, seat.columnIndex, seat.status)"
            >
              {{ seat.columnIndex + 1 }}
            </div>
          </div>
        </div>

        <div class="legend">
          <div class="legend-item">
            <div class="seat-sample available"></div>
            <span>可选</span>
          </div>
          <div class="legend-item">
            <div class="seat-sample selected"></div>
            <span>已选</span>
          </div>
          <div class="legend-item">
            <div class="seat-sample occupied"></div>
            <span>已售</span>
          </div>
        </div>
      </div>

      <div class="selected-seats-info">
        <h3>已选座位: {{ selectedSeats.length > 0 ? selectedSeats.map(s => `${s.rowIndex + 1}排${s.columnIndex + 1}号`).join(', ') : '未选择' }}</h3>
        <p>总价: ¥{{ totalPrice.toFixed(2) }}</p>
      </div>

      <div class="actions">
        <el-button type="primary" :disabled="selectedSeats.length === 0" @click="submitOrder">提交订单</el-button>
        <el-button @click="goBack">返回</el-button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import axios from 'axios';
import { useUserStore } from '../store/user';

const route = useRoute();
const router = useRouter();
const userStore = useUserStore();

// 类型定义
interface Seat {
  id?: number;
  rowIndex: number;
  columnIndex: number;
  status: 'AVAILABLE' | 'OCCUPIED';
  showtimeId?: number;
}

interface Row {
  rowIndex: number;
  seats: Seat[];
}

interface Hall {
  id: number;
  name: string;
  rows: number;
  columns: number;
}

interface Movie {
  id: number;
  title: string;
}

interface Showtime {
  id: number;
  movieId: number;
  movie: Movie;
  hallName: string;
  showTime: string;
  price: number;
  availableSeats: number;
}

// 响应式数据
const loading = ref(true);
const showtime = ref<Showtime | null>(null);
const seatMap = ref<Row[]>([]);
const selectedSeats = ref<Seat[]>([]);

// 计算总价
const totalPrice = computed(() => {
  if (!showtime.value) return 0;
  return selectedSeats.value.length * showtime.value.price;
});

// 格式化日期时间
const formatDateTime = (dateTimeStr?: string) => {
  if (!dateTimeStr) return '';
  const date = new Date(dateTimeStr);
  return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
};

// 判断座位是否已选
const isSelected = (rowIndex: number, columnIndex: number) => {
  return selectedSeats.value.some(
    (seat) => seat.rowIndex === rowIndex && seat.columnIndex === columnIndex
  );
};

// 切换座位选择状态
const toggleSeat = (rowIndex: number, columnIndex: number, status: string) => {
  if (status === 'OCCUPIED') return;

  const seatIndex = selectedSeats.value.findIndex(
    (seat) => seat.rowIndex === rowIndex && seat.columnIndex === columnIndex
  );

  if (seatIndex > -1) {
    // 如果已选择，则取消选择
    selectedSeats.value.splice(seatIndex, 1);
  } else {
    // 如果票数超过4张，则提示
    if (selectedSeats.value.length >= 4) {
      ElMessage.warning('一次最多只能选择4个座位');
      return;
    }

    // 如果未选择，则添加到已选座位
    selectedSeats.value.push({
      rowIndex,
      columnIndex,
      status: 'AVAILABLE'
    });
  }
};

// 获取场次信息和座位数据
const fetchShowtimeAndSeats = async () => {
  try {
    loading.value = true;
    const showtimeId = route.params.showtimeId;

    // 获取场次信息
    const showtimeResponse = await axios.get(`/api/showtimes/${showtimeId}`, {
      headers: { Authorization: `Bearer ${userStore.token}` }
    });

    showtime.value = showtimeResponse.data;

    // 获取座位信息
    const seatsResponse = await axios.get(`/api/showtimes/${showtimeId}/seats`, {
      headers: { Authorization: `Bearer ${userStore.token}` }
    });

    // 将后端返回的座位列表转换为前端需要的格式
    const seats = seatsResponse.data;

    // 如果没有座位数据，则初始化座位
    if (seats.length === 0) {
      // 固定初始化10行10列的座位
      await initializeSeats(showtimeId, 10, 10);
      // 重新获取座位信息
      const newSeatsResponse = await axios.get(`/api/showtimes/${showtimeId}/seats`, {
        headers: { Authorization: `Bearer ${userStore.token}` }
      });
      processSeats(newSeatsResponse.data);
    } else {
      // 确保座位数据是10行10列
      if (seats.length !== 100) {
        console.warn(`座位数量异常: ${seats.length}，应为100个`);
      }
      processSeats(seats);
    }
  } catch (error) {
    console.error('获取场次和座位信息失败', error);
    ElMessage.error('获取座位信息失败，请稍后再试');
  } finally {
    loading.value = false;
  }
};

// 处理座位数据，将其转换为行列格式
const processSeats = (seats: any[]) => {
  // 固定为10行10列
  const maxRow = 9; // 0-9对应1-10行
  const maxCol = 9; // 0-9对应1-10列

  // 创建座位地图
  const rows: Row[] = [];

  // 初始化每一行
  for (let i = 0; i <= maxRow; i++) {
    const row: Row = {
      rowIndex: i,
      seats: []
    };

    // 初始化每一列
    for (let j = 0; j <= maxCol; j++) {
      row.seats.push({
        rowIndex: i,
        columnIndex: j,
        status: 'AVAILABLE'
      });
    }

    rows.push(row);
  }

  // 更新座位状态
  seats.forEach(seat => {
    if (seat.rowIndex <= maxRow && seat.columnIndex <= maxCol) {
      rows[seat.rowIndex].seats[seat.columnIndex].status = seat.status;
      rows[seat.rowIndex].seats[seat.columnIndex].id = seat.id;
      rows[seat.rowIndex].seats[seat.columnIndex].showtimeId = seat.showtimeId;
    }
  });

  seatMap.value = rows;
};

// 初始化座位
const initializeSeats = async (showtimeId: string | string[], rows: number, columns: number) => {
  try {
    await axios.post(`/api/showtimes/${showtimeId}/seats/initialize`, null, {
      params: { rows, columns },
      headers: { Authorization: `Bearer ${userStore.token}` }
    });
  } catch (error) {
    console.error('初始化座位失败', error);
    ElMessage.error('初始化座位失败，请稍后再试');
  }
};

// 提交订单
const submitOrder = async () => {
  if (selectedSeats.value.length === 0) {
    ElMessage.warning('请至少选择一个座位');
    return;
  }

  try {
    const confirmed = await ElMessageBox.confirm(
      `您选择了${selectedSeats.value.length}个座位，总价¥${totalPrice.value.toFixed(2)}，是否确认下单？`,
      '确认订单',
      {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning'
      }
    ).then(() => true)
    .catch(() => false);

    if (!confirmed) return;

    // 检查用户余额是否足够
    if (userStore.user && userStore.user.balance !== null && userStore.user.balance !== undefined && userStore.user.balance < totalPrice.value) {
      ElMessage.error('余额不足，请先充值');
      return;
    }

    const orderData = {
      showtimeId: showtime.value?.id,
      userId: userStore.user?.id,
      price: totalPrice.value,
      movieId: showtime.value?.movieId,
      seatInfo: selectedSeats.value.map(seat => `${seat.rowIndex + 1}排${seat.columnIndex + 1}号`).join(',')
    };

    const response = await axios.post('/api/orders', orderData);

    // 更新座位状态
    for (const seat of selectedSeats.value) {
      try {
        // 找到座位ID
        const seatId = seatMap.value[seat.rowIndex].seats[seat.columnIndex].id;
        if (seatId) {
          await axios.put(`/api/seats/${seatId}/status`, null, {
            params: { status: 'OCCUPIED' } // 使用后端定义的常量
          });
        }
      } catch (e) {
        console.error('更新座位状态失败', e);
      }
    }

    ElMessage.success('订单创建成功');

    // 尝试刷新用户信息（更新余额）
    try {
      if (userStore.isLoggedIn) {
        await userStore.fetchUserInfo();
      }
    } catch (e) {
      console.error('获取用户信息失败', e);
    }

    // 跳转到订单详情页
    router.push(`/order/${response.data.id}`);
  } catch (error: any) {
    console.error('创建订单失败', error);
    ElMessage.error(error.response?.data?.message || '创建订单失败，请稍后再试');
  }
};

// 返回
const goBack = () => {
  router.back();
};

// 定时刷新座位状态的定时器
let refreshTimer: number | null = null;

// 添加页面激活时的刷新逻辑
const refreshSeats = async () => {
  try {
    const showtimeId = route.params.showtimeId;
    const seatsResponse = await axios.get(`/api/showtimes/${showtimeId}/seats`, {
      headers: { Authorization: `Bearer ${userStore.token}` }
    });
    processSeats(seatsResponse.data);
  } catch (error) {
    console.error('刷新座位信息失败', error);
  }
};

// 组件挂载时获取数据并启动定时刷新
onMounted(() => {
  fetchShowtimeAndSeats();

  // 每10秒刷新一次座位状态
  refreshTimer = window.setInterval(() => {
    refreshSeats();
  }, 10000);
});

// 组件卸载时清除定时器
onUnmounted(() => {
  if (refreshTimer !== null) {
    clearInterval(refreshTimer);
    refreshTimer = null;
  }

  // 移除事件监听器
  document.removeEventListener('visibilitychange', handleVisibilityChange);
});

// 页面可见性变化处理函数
const handleVisibilityChange = () => {
  if (document.visibilityState === 'visible') {
    refreshSeats();
  }
};

// 页面可见性变化时刷新座位状态
document.addEventListener('visibilitychange', handleVisibilityChange);
</script>

<style scoped>
.seat-selection-container {
  max-width: 1000px;
  margin: 0 auto;
  padding: 20px;
}

.loading {
  padding: 40px 0;
}

.showtime-info {
  margin-bottom: 30px;
  padding: 15px;
  background-color: rgba(245, 247, 250, 0.85);
  border-radius: 8px;
}

.seat-map-container {
  margin: 30px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: rgba(255, 255, 255, 0.85);
  padding: 20px;
  border-radius: 8px;
}

.screen {
  width: 70%;
  height: 40px;
  background: linear-gradient(to bottom, #d3d3d3, #f5f5f5);
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 30px;
  border-radius: 5px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1);
  font-weight: bold;
}

.seat-map {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 20px;
}

.seat-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.row-label {
  width: 30px;
  text-align: center;
  font-weight: bold;
}

.seat {
  width: 35px;
  height: 35px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 5px;
  cursor: pointer;
  font-size: 12px;
  transition: all 0.3s;
}

.seat.available {
  background-color: #e6f7ff;
  border: 1px solid #91d5ff;
}

.seat.selected {
  background-color: #52c41a;
  color: white;
  border: 1px solid #52c41a;
}

.seat.occupied {
  background-color: #f5f5f5;
  color: #bfbfbf;
  cursor: not-allowed;
  border: 1px solid #d9d9d9;
}

.seat:hover:not(.occupied) {
  transform: scale(1.1);
}

.legend {
  display: flex;
  justify-content: center;
  gap: 20px;
  margin-top: 20px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
}

.seat-sample {
  width: 20px;
  height: 20px;
  border-radius: 3px;
}

.seat-sample.available {
  background-color: #e6f7ff;
  border: 1px solid #91d5ff;
}

.seat-sample.selected {
  background-color: #52c41a;
  border: 1px solid #52c41a;
}

.seat-sample.occupied {
  background-color: #f5f5f5;
  border: 1px solid #d9d9d9;
}

.selected-seats-info {
  margin: 20px 0;
  padding: 15px;
  background-color: rgba(246, 255, 237, 0.85);
  border-radius: 8px;
  border: 1px solid rgba(183, 235, 143, 0.5);
}

.actions {
  margin-top: 30px;
  display: flex;
  justify-content: center;
  gap: 15px;
}
</style>